package com.wl.api.service.system.impl;

import static com.wl.api.common.utils.PageInfo.transformPage;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.wl.api.common.utils.BeanUtils;
import com.wl.api.common.utils.CollectionUtil;
import com.wl.api.common.utils.ObjectUtil;
import com.wl.api.common.utils.PageInfo;
import com.wl.api.common.utils.constant.ClientConstant;
import com.wl.api.dto.system.SecurityChannelAreaLadderPriceDTO;
import com.wl.api.dto.system.SecurityChannelAreaServicePartnerDTO;
import com.wl.api.mapper.system.SecurityChannelAreaServicePartnerMapper;
import com.wl.api.model.system.SecurityChannelAreaLadderPrice;
import com.wl.api.model.system.SecurityChannelAreaService;
import com.wl.api.model.system.SecurityChannelAreaServicePartner;
import com.wl.api.model.system.SecurityChannelPartner;
import com.wl.api.service.system.ISecurityChannelAreaLadderPriceService;
import com.wl.api.service.system.ISecurityChannelAreaServicePartnerService;
import com.wl.api.service.system.ISecurityChannelAreaServiceService;
import com.wl.api.service.system.ISecurityChannelPartnerService;

/**
 *
 * SecurityChannelAreaServicePartner 表数据服务层接口实现类
 *
 */
@Service
public class SecurityChannelAreaServicePartnerServiceImpl extends ServiceImpl<SecurityChannelAreaServicePartnerMapper, SecurityChannelAreaServicePartner> implements ISecurityChannelAreaServicePartnerService {

	@Autowired
	ISecurityChannelAreaLadderPriceService areaLadderPriceService;
	@Autowired
	ISecurityChannelAreaServiceService areaServiceService;
	@Autowired
	ISecurityChannelPartnerService channelPartnerService;
	
	@Override
	public int addServicePartner(SecurityChannelAreaServicePartnerDTO param) {
		Assert.notNull(param);
		Assert.notNull(param.getServiceId());
		SecurityChannelAreaService data = areaServiceService.selectById(param.getServiceId());
		Assert.notNull(data);
		Assert.isTrue(Objects.equals(data.getFeeType(), ClientConstant.FEE_TYPE_PICK_UP));
		
		 Map<String, BigDecimal> btAmtMap = getBtAmountMap(param.getPickupLadderList());
		SecurityChannelAreaServicePartner entity = BeanUtils.copyProperties(param, SecurityChannelAreaServicePartner.class);
		insert(entity.buildBtAmt(btAmtMap.get("min"), btAmtMap.get("max")));
		List<SecurityChannelAreaLadderPrice>
			list = param.getPickupLadderList().parallelStream()
						.map(s -> SecurityChannelAreaLadderPrice.builder().feeType(ClientConstant.FEE_TYPE_PICK_UP).amount(s.getAmount())
						.weightFrom(s.getWeightFrom()).weightTo(s.getWeightTo()).updateUser(param.getUpdateUser()).updateUserId(param.getUpdateUserId())
						.areaServiceId(entity.getId()).createTime(new Date()).build()).collect(Collectors.toList());
		
		areaLadderPriceService.insertBatch(list);
		return entity.getId();
	}
	
	/**
	 * 获取最大值, 最小值
	 * @param pickupLadderList
	 * @return
	 */
	private Map<String, BigDecimal> getBtAmountMap(List<SecurityChannelAreaLadderPriceDTO> pickupLadderList) {
		Assert.notEmpty(pickupLadderList);
		Set<BigDecimal> set = new HashSet<>();
		Map<String, BigDecimal> map = new HashMap<>();
		pickupLadderList.forEach(s -> set.add(s.getAmount()));
		BigDecimal[] arr =  set.toArray(new BigDecimal[0]); 
		Arrays.sort(arr);
		map.put("min", arr[0]);
		map.put("max", arr.length> 1 ? arr[arr.length-1]: arr[0]);
		return map;
	}
	
	
	@Override
	public int updateServicePartner(SecurityChannelAreaServicePartnerDTO param) {
		Assert.notNull(param.getId());
		Assert.notNull(param.getServiceId());
		SecurityChannelAreaService data = areaServiceService.selectById(param.getServiceId());
		Assert.notNull(data);
		Assert.isTrue(Objects.equals(data.getFeeType(), ClientConstant.FEE_TYPE_PICK_UP));
		
		List<SecurityChannelAreaLadderPrice> source =  getAreaServiceLadderList(SecurityChannelAreaLadderPrice.builder().areaServiceId(param.getId()).feeType(data.getFeeType()).build());
		List<Long> delIds = new ArrayList<Long>();
		List<SecurityChannelAreaLadderPriceDTO> updateList = param.getPickupLadderList().parallelStream().filter(s -> !ObjectUtil.isEmpty(s.getId())).collect(Collectors.toList()); 
		List<SecurityChannelAreaLadderPriceDTO> insertList = param.getPickupLadderList().parallelStream().filter(s -> ObjectUtil.isEmpty(s.getId())).collect(Collectors.toList());
		 Map<String, BigDecimal> btAmtMap = getBtAmountMap(param.getPickupLadderList());
		//del 
		if (!CollectionUtil.isEmpty(source)) {
			for(SecurityChannelAreaLadderPrice sc: source) {
				if (CollectionUtil.isEmpty(updateList)) {
					delIds.add(sc.getId());
					continue;
				}
				if (updateList.parallelStream().noneMatch(s -> Objects.equals(s.getId(), sc.getId()))) {
					delIds.add(sc.getId());
					continue;
				}
			}
		}
		
		if(!CollectionUtil.isEmpty(delIds)) {
			areaLadderPriceService.deleteBatchIds(delIds);
		}
		if (!CollectionUtil.isEmpty(updateList)) {
			areaLadderPriceService.updateBatchById(BeanUtils.copyProperties(updateList, SecurityChannelAreaLadderPrice.class).parallelStream()
					.map(s -> s.buildServiceId(param.getServiceId()).buildFeeType(ClientConstant.FEE_TYPE_PICK_UP)).collect(Collectors.toList()));
		}
		if (!CollectionUtil.isEmpty(insertList)) {
			areaLadderPriceService.insertBatch(BeanUtils.copyProperties(insertList, SecurityChannelAreaLadderPrice.class)
					.parallelStream()
					.map(s -> s.buildServiceId(param.getServiceId()).buildFeeType(ClientConstant.FEE_TYPE_PICK_UP)).collect(Collectors.toList()));
		}
		updateById(BeanUtils.copyProperties(param, SecurityChannelAreaServicePartner.class).buildBtAmt(btAmtMap.get("min"), btAmtMap.get("max")));
		return param.getId();
	}

	public List<SecurityChannelAreaLadderPrice> getAreaServiceLadderList(SecurityChannelAreaLadderPrice param) {
		
		return areaLadderPriceService.selectList(new EntityWrapper<SecurityChannelAreaLadderPrice>(param));
	}

	@Override
	public PageInfo<SecurityChannelAreaServicePartnerDTO> getServicePartnerList(
			SecurityChannelAreaServicePartnerDTO param) {
		
		Wrapper<SecurityChannelAreaServicePartner> wrapper =
				new EntityWrapper<SecurityChannelAreaServicePartner>().where(" 1=1 ");
		if (param.getServiceId() != null) {
			wrapper.andNewSimple("service_id", param.getServiceId());
		}
		if (param.getStatus() != null) {
			wrapper.andNewSimple("status", param.getStatus());
		}
		
		Page<SecurityChannelAreaServicePartner> 
		   		page = selectPage(new Page<>(param.getPage(), param.getPageSize(), "create_time", false), wrapper);
		PageInfo<SecurityChannelAreaServicePartnerDTO> 
		pageInfo = transformPage(SecurityChannelAreaServicePartnerDTO.class, page);
		
		if (page != null && !CollectionUtil.isEmpty(page.getRecords())) {
			
			//合作商列表
			List<Integer> partnerList =  page.getRecords().parallelStream().filter(s -> Objects.nonNull(s.getPartnerId())).map(s -> s.getPartnerId()).distinct().collect(Collectors.toList());
			Map<Integer, String> partnerMap = new HashMap<>();
			if (!CollectionUtils.isEmpty(partnerList)) {
				List<SecurityChannelPartner> list = channelPartnerService.selectBatchIds(partnerList);
				if (!CollectionUtil.isEmpty(list)) {
					partnerMap = list.parallelStream().collect(Collectors.toMap(SecurityChannelPartner::getPartnerId, SecurityChannelPartner::getName));
				}
			}
			
			List<SecurityChannelAreaLadderPrice> ladderPrice = areaLadderPriceService.selectList(new EntityWrapper<SecurityChannelAreaLadderPrice>().where("fee_type={0}", ClientConstant.FEE_TYPE_PICK_UP).in("area_service_id", page.getRecords().parallelStream().map(s -> s.getId()).collect(Collectors.toList())));	
			if (!CollectionUtil.isEmpty(ladderPrice)) {
				Map<Integer, List<SecurityChannelAreaLadderPrice>> map = 
							ladderPrice.parallelStream().collect(Collectors.groupingBy(SecurityChannelAreaLadderPrice::getAreaServiceId));
				for (SecurityChannelAreaServicePartnerDTO dd: pageInfo.getItems()) {
					dd.setPickupLadderList(BeanUtils.copyProperties(map.get(dd.getId()), SecurityChannelAreaLadderPriceDTO.class));
					dd.setPartnerName(partnerMap.get(dd.getPartnerId()));
				}
				
			}
		}
		
		return pageInfo;
	}

	@Override
	public SecurityChannelAreaServicePartnerDTO getPartnerDetail(Integer id) {
		SecurityChannelAreaServicePartner data = selectById(id);
		Assert.notNull(data);
		
		//合作商
		String partnerName = null;
		if (Objects.nonNull(data.getPartnerId())) {
			SecurityChannelPartner partner = channelPartnerService.selectById(data.getPartnerId());
			if (Objects.nonNull(partner)) {
				partnerName = partner.getName(); 
			}
		}
		
		List<SecurityChannelAreaLadderPrice> ladderPrice = areaLadderPriceService.selectList(new EntityWrapper<SecurityChannelAreaLadderPrice>().where("fee_type={0}", ClientConstant.FEE_TYPE_PICK_UP).andNewSimple("area_service_id", id));	
		return BeanUtils.copyProperties(data, SecurityChannelAreaServicePartnerDTO.class).buildLadderList(BeanUtils.copyProperties(ladderPrice, SecurityChannelAreaLadderPriceDTO.class)).buildPartnerName(partnerName);
	}

}